#!/bin/bash

set -o errexit

test_dir=$(realpath $(dirname $0))
. ${test_dir}/../functions

set_debug

get_node_id_from_pmm() {
	local -a nodeList=()
	for instance in $(kubectl_bin get pods --no-headers -l app.kubernetes.io/component=pxc --output=custom-columns='NAME:.metadata.name'); do
		nodeList+=($(kubectl_bin exec -n "$namespace" $instance -c pmm-client -- pmm-admin status --json | jq -r '.pmm_agent_status.node_id'))
	done

	echo "${nodeList[@]}"
}

does_node_id_exists() {
	local -a nodeList=("$@")
	local -a nodeList_from_pmm=()
	for node_id in "${nodeList[@]}"; do
		nodeList_from_pmm+=($(kubectl_bin exec -n "${namespace}" monitoring-0 -- pmm-admin --server-url=https://admin:admin@$(get_service_ip monitoring-service)/ --server-insecure-tls inventory list nodes --node-type=CONTAINER_NODE | grep $node_id | awk '{print $4}'))
	done

	echo "${nodeList_from_pmm[@]}"
}

cluster="monitoring"

create_infra $namespace
deploy_helm $namespace

desc 'install PMM Server'
platform=kubernetes
helm uninstall monitoring || :
if [ ! -z "$OPENSHIFT" ]; then
	platform=openshift
	oc create sa pmm-server
	oc adm policy add-scc-to-user privileged -z pmm-server
	if [ -n "$OPERATOR_NS" ]; then
		timeout 30 oc delete clusterrolebinding $(kubectl get clusterrolebinding | grep 'pmm-pxc-operator-' | awk '{print $1}') || :
		oc create clusterrolebinding pmm-pxc-operator-cluster-wide --clusterrole=percona-xtradb-cluster-operator --serviceaccount=$namespace:pmm-server
		oc patch clusterrole/percona-xtradb-cluster-operator --type json -p='[{"op":"add","path": "/rules/-","value":{"apiGroups":["security.openshift.io"],"resources":["securitycontextconstraints"],"verbs":["use"],"resourceNames":["privileged"]}}]' ${OPERATOR_NS:+-n $OPERATOR_NS}
	else
		oc create rolebinding pmm-pxc-operator-namespace-only --role percona-xtradb-cluster-operator --serviceaccount=$namespace:pmm-server
		oc patch role/percona-xtradb-cluster-operator --type json -p='[{"op":"add","path": "/rules/-","value":{"apiGroups":["security.openshift.io"],"resources":["securitycontextconstraints"],"verbs":["use"],"resourceNames":["privileged"]}}]'
	fi
	retry 10 60 helm install monitoring --set imageTag=$IMAGE_PMM_SERVER_TAG --set imageRepo=$IMAGE_PMM_SERVER_REPO --set platform=$platform --set sa=pmm-server --set supresshttp2=false https://percona-charts.storage.googleapis.com/pmm-server-${PMM_SERVER_VER}.tgz
else
	helm install monitoring --set imageTag=$IMAGE_PMM_SERVER_TAG --set imageRepo=$IMAGE_PMM_SERVER_REPO --set platform=$platform https://percona-charts.storage.googleapis.com/pmm-server-${PMM_SERVER_VER}.tgz
fi
SERVICE="postgres"
until kubectl_bin exec monitoring-0 -- bash -c "pgrep -x $SERVICE >/dev/null"; do
	echo "Retry $retry"
	sleep 5
	let retry+=1
	if [ $retry -ge 20 ]; then
		echo "Max retry count $retry reached. Pmm-server can't start"
		exit 1
	fi
done
ADMIN_PASSWORD=$(kubectl_bin exec monitoring-0 -- bash -c "printenv | grep ADMIN_PASSWORD | cut -d '=' -f2")
sleep 5
kubectl_bin exec monitoring-0 -- bash -c "grafana-cli --homepath=/usr/share/grafana --config=/etc/grafana/grafana.ini admin reset-admin-password $ADMIN_PASSWORD"

desc 'create PXC cluster'
spinup_pxc "$cluster" "$test_dir/conf/$cluster.yml" 3 120

desc 'add PMM API key to secret'
API_KEY=$(curl --insecure -X POST -H "Content-Type: application/json" -d '{"name":"operator", "role": "Admin"}' "https://admin:$ADMIN_PASSWORD@$(get_service_endpoint monitoring-service)/graph/api/auth/keys" | jq .key)
kubectl_bin patch secret my-cluster-secrets --type merge --patch '{"stringData": {"pmmserverkey": '"$API_KEY"'}}'

wait_for_generation "sts/$cluster-pxc" 2
wait_for_generation "sts/$cluster-haproxy" 2
sleep 10
kubectl wait pod -l 'app.kubernetes.io/managed-by=percona-xtradb-cluster-operator' --for=condition=ready --timeout=600s

desc 'add new PMM API key to secret'
API_KEY_NEW=$(curl --insecure -X POST -H "Content-Type: application/json" -d '{"name":"operator-new", "role": "Admin"}' "https://admin:$ADMIN_PASSWORD@$(get_service_endpoint monitoring-service)/graph/api/auth/keys" | jq .key)
kubectl_bin patch secret my-cluster-secrets --type merge --patch '{"stringData": {"pmmserverkey": '"$API_KEY_NEW"'}}'

desc 'delete old PMM key'
ID_API_KEY_OLD=$(curl --insecure -X GET "https://admin:$ADMIN_PASSWORD@$(get_service_endpoint monitoring-service)/graph/api/auth/keys" | jq '.[] | select( .name == "operator").id')
curl --insecure -X DELETE "https://admin:$ADMIN_PASSWORD@$(get_service_endpoint monitoring-service)/graph/api/auth/keys/$ID_API_KEY_OLD"

wait_for_generation "sts/$cluster-pxc" 3
wait_for_generation "sts/$cluster-haproxy" 3
sleep 10
kubectl wait pod -l 'app.kubernetes.io/managed-by=percona-xtradb-cluster-operator' --for=condition=ready --timeout=600s

desc 'check if pmm-client container enabled'
compare_kubectl statefulset/$cluster-pxc
compare_kubectl statefulset/$cluster-haproxy

desc 'check mysql metrics'
get_metric_values node_boot_time_seconds $namespace-$cluster-pxc-0 admin:admin
get_metric_values mysql_global_status_uptime $namespace-$cluster-pxc-0 admin:admin

# wait for QAN and metrics
sleep 90

desc 'check haproxy metrics'
get_metric_values haproxy_backend_status $namespace-$cluster-haproxy-0 admin:admin
get_metric_values haproxy_backend_active_servers $namespace-$cluster-haproxy-0 admin:admin

desc 'check QAN data'
get_qan20_values $cluster-pxc-0 admin:admin

nodeList=($(get_node_id_from_pmm))
nodeList_from_pmm=($(does_node_id_exists "${nodeList[@]}"))
for node_id in "${nodeList_from_pmm[@]}"; do
	if [ -z "$node_id" ]; then
		echo "Can't get $node_id node_id from PMM server"
		exit 1
	fi
done

kubectl_bin patch pxc ${cluster} --type json -p='[{"op":"add","path":"/spec/pause","value":true}]'
wait_for_delete "pod/${cluster}-pxc-0"

does_node_id_exists_in_pmm=($(does_node_id_exists "${nodeList[@]}"))
for instance in "${does_node_id_exists_in_pmm[@]}"; do
	if [ -n "$instance" ]; then
		echo "The $instance pod was not deleted from server inventory"
		exit 1
	fi
done

if [[ -n ${OPENSHIFT} ]]; then
	oc adm policy remove-scc-from-user privileged -z pmm-server
	if [ -n "$OPERATOR_NS" ]; then
		oc delete clusterrolebinding pmm-pxc-operator-cluster-wide
	else
		oc delete rolebinding pmm-pxc-operator-namespace-only
	fi
fi
helm uninstall monitoring
destroy $namespace
desc "test passed"
